#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <cassert>

namespace maglog {

#define BUFFER_DEFAULT_SIZE (1*1024*1024)       // 默认缓冲区大小为1MB
#define BUFFER_INCREMENT_SIZE (1*1024*1024)     // 缓冲区每次扩展的大小为1MB
#define BUFFER_THRESHOLD_SIZE (10*1024*1024)    // 缓冲区的阈值大小为10MB

// Buffer类：用于管理日志缓冲区，支持读取、写入、扩展等操作
class Buffer {
    public:
        // 构造函数：初始化读取和写入索引，并设置缓冲区的初始大小
        Buffer() : _reader_idx(0), _writer_idx(0), _v(BUFFER_DEFAULT_SIZE) {}

        // 检查缓冲区是否为空
        bool empty() { return _reader_idx == _writer_idx; }

        // 获取可读的数据大小
        size_t readAbleSize() { return _writer_idx - _reader_idx; }

        // 获取可写的空间大小
        size_t writeAbleSize() { return _v.size() - _writer_idx; }

        // 重置缓冲区，清除所有数据
        void reset() { _reader_idx = _writer_idx = 0; }

        // 交换当前缓冲区与另一个缓冲区的数据
        void swap(Buffer &buf)  {
            _v.swap(buf._v);
            std::swap(_reader_idx, buf._reader_idx);
            std::swap(_writer_idx, buf._writer_idx);
        }

        // 向缓冲区中写入数据
        void push(const char *data, size_t len) { 
            assert(len <= writeAbleSize());  // 确保有足够的空间写入数据
            ensureEnoughSpace(len);          // 确保有足够的空间
            std::copy(data, data + len, &_v[_writer_idx]); // 将数据拷贝到缓冲区
            _writer_idx += len;              // 更新写入索引
        }

        // 获取缓冲区中可读数据的起始位置
        const char* begin() { return &_v[_reader_idx]; }

        // 从缓冲区中移除指定长度的数据
        void pop(size_t len) { 
            _reader_idx += len; 
            assert(_reader_idx <= _writer_idx); // 确保读取索引不超过写入索引
        }

    protected:
        // 确保缓冲区有足够的空间容纳新数据
        void ensureEnoughSpace(size_t len) {
            if (len <= writeAbleSize()) return;

            // 根据当前缓冲区的大小决定扩展的大小
            size_t new_capacity;
            if (_v.size() < BUFFER_THRESHOLD_SIZE)
                new_capacity = _v.size() * 2 + len;
            else
                new_capacity = _v.size() + BUFFER_INCREMENT_SIZE + len;

            _v.resize(new_capacity); // 扩展缓冲区
        }

    private:
        size_t _reader_idx;          // 读取索引
        size_t _writer_idx;          // 写入索引
        std::vector<char> _v;        // 缓冲区数据存储
};

} // namespace maglog
